﻿using System;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace BGYMqttServer
{
    /// <summary>
    /// 提供Json序列化
    /// CamelCase风格
    /// 中文不转码
    /// 时间转换本地时间并ISO8601格式输出
    /// </summary>
    public static class JsonTextSerializer
    {
        /// <summary>
        /// json选项
        /// </summary>
        private static readonly JsonSerializerOptions jsonOptions;

        /// <summary>
        /// 供Json序列化
        /// </summary>
        static JsonTextSerializer()
        {
            jsonOptions = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true,
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
            };
            jsonOptions.Converters.Add(JsonLocalDateTimeConverter.Default);
        }

        /// <summary>
        /// 序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string Serialize<T>(T value)
        {
            return JsonSerializer.Serialize(value, jsonOptions);
        }

        /// <summary>
        /// 序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        public static byte[] SerializeToUtf8Bytes<T>(T value)
        {
            return JsonSerializer.SerializeToUtf8Bytes(value, jsonOptions);
        }

        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="value"></param>
        /// <param name="valueType"></param>
        public static byte[] SerializeToUtf8Bytes(object value, Type valueType)
        {
            return JsonSerializer.SerializeToUtf8Bytes(value, valueType, jsonOptions);
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public static T Deserialize<T>(string json)
        {
            return JsonSerializer.Deserialize<T>(json, jsonOptions);
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="json"></param>
        /// <param name="returnType"></param>
        /// <returns></returns>
        public static object Deserialize(string json, Type returnType)
        {
            return JsonSerializer.Deserialize(json, returnType, jsonOptions);
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public static T Deserialize<T>(ReadOnlySpan<byte> json)
        {
            return JsonSerializer.Deserialize<T>(json, jsonOptions);
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="json"></param>
        /// <param name="returnType"></param>
        /// <returns></returns>
        public static object Deserialize(ReadOnlySpan<byte> json, Type returnType)
        {
            return JsonSerializer.Deserialize(json, returnType, jsonOptions);
        }
    }
}
